package com.example.fengyungo_user.activity.message;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.fengyungo_user.MyWebSocketClient;
import com.example.fengyungo_user.R;
import com.example.fengyungo_user.activity.BaseActivity;
import com.example.fengyungo_user.adapter.ChatMessageAdapter;
import com.example.fengyungo_user.constant.MessageConstant;
import com.example.fengyungo_user.domain.ChatMessage;
import com.example.fengyungo_user.domain.Message;
import com.example.fengyungo_user.domain.User;
import com.example.fengyungo_user.service.WebSocketService;
import com.example.fengyungo_user.utils.OkHttpUtils;
import com.example.fengyungo_user.utils.ThreadPoolUtil;
import com.example.fengyungo_user.utils.UserUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 聊天界面
 *
 * @author XLR
 */
public class ChatActivity extends BaseActivity implements View.OnClickListener {

    private static final String TAG = "ChatActivity";
    /**
     * 返回按钮
     */
    ImageButton back;
    /**
     * 发送按钮
     */
    Button send;
    /**
     * 输入的内容
     */
    String input;
    /**
     * 发送的内容的输入框
     */
    EditText inputEditText;
    /**
     * RecyclerView
     */
    RecyclerView recyclerView;
    /**
     * LinearLayoutManager
     */
    LinearLayoutManager layoutManager;
    /**
     * ChatMessageAdapter
     */
    ChatMessageAdapter adapter;
    /**
     * 聊天记录
     */
    List<ChatMessage> chatMessageList;
    /**
     * websocket的url
     */
    String url;
    /**
     * 用户id
     */
    String userId;
    /**
     * 用户
     */
    User user;
    /**
     * 司机昵称
     */
    private String driverNickname;
    /**
     * MyWebSocketClient
     */
    MyWebSocketClient myWebSocketClient;
    /**
     * 发送内容
     */
    String content;
    /**
     * 司机id
     */
    String driverId;
    /**
     * webSocketClientBinder
     */
    WebSocketService.WebSocketClientBinder binder;
    /**
     * webSocketClientBinder
     */
    WebSocketService webSocketService;
    /**
     * 用户未读数
     */
    int userUnread;
    /**
     * 看得见的消息数
     */
    int num;
    /**
     * 下拉刷新
     */
    SwipeRefreshLayout swipeRefreshLayout;
    /**
     * 后端传过来的
     */
    List<Message> messages;
    /**
     * ChatMessageReceiver聊天信息广播接收器
     */
    ChatMessageReceiver chatMessageReceiver;
    /**
     * 刷新是否继续增加add
     */
    boolean isAdd = true;
    /**
     * 使用本地广播
     */
    LocalBroadcastManager localBroadcastManager;
    /**
     * 服务绑定后
     */
    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            binder = (WebSocketService.WebSocketClientBinder) iBinder;
            webSocketService = binder.getService();
            myWebSocketClient = webSocketService.myWebSocketClient;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    /**
     * 聊天信息广播接收器
     */
    class ChatMessageReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String message = intent.getStringExtra(MessageConstant.MESSAGE);
            Log.d(TAG, "onReceive: message=" + message);

            JSONObject jsonObject;
            String content;
            String senderId;

            jsonObject = JSON.parseObject(message);
            content = jsonObject.getString(MessageConstant.CONTENT);
            // 发送者（用户）id
            senderId = jsonObject.getString(MessageConstant.SENDER_ID);

            // 用户在发送方司机的聊天窗口
            if (senderId.equals(driverId)) {
                ChatMessage chatMessage = new ChatMessage();
                chatMessage.setContent(content);
                chatMessage.setMessageType(ChatMessage.FROM_RECEIVER);
                chatMessage.setDriverId(driverId);
                chatMessageList.add(chatMessage);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // 刷新RecyclerView的显示
                        adapter.notifyItemInserted(chatMessageList.size() - 1);
                        // 定位到最后一行
                        recyclerView.scrollToPosition(chatMessageList.size() - 1);
                    }
                });
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        // 获取用户信息
        user = UserUtils.getUserInfo(this);
        userId = user.getUserId();

        // 获取用户信息
        Intent intent = getIntent();
        driverId = intent.getStringExtra(MessageConstant.DRIVER_ID);
        userUnread = intent.getIntExtra(MessageConstant.USER_UNREAD, 0);
        driverNickname = intent.getStringExtra(MessageConstant.DRIVER_NICKNAME);

        // 设置顶部文字为对方昵称
        TextView nicknameTextView = findViewById(R.id.tv_nickname);
        nicknameTextView.setText(driverNickname);

        // 初始化聊天记录数，展示未读以上的消息数
        num = userUnread + 5;

        // 绑定websocketService服务
        bindService();

        // 动态注册广播，动态注册的广播接收器要记得取消注册
        Log.d(TAG, "onCreate: registerReceiver");
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("webSocketService");
        chatMessageReceiver = new ChatMessageReceiver();
        localBroadcastManager.registerReceiver(chatMessageReceiver, intentFilter);

        // 查询聊天记录
        recyclerView = findViewById(R.id.recyclerview_chat);
        layoutManager = new LinearLayoutManager(this);
        getMessages();

        inputEditText = findViewById(R.id.input_text);

        back = findViewById(R.id.back);
        back.setOnClickListener(this);

        send = findViewById(R.id.send_button);
        send.setOnClickListener(this);

        swipeRefreshLayout = findViewById(R.id.refresh);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                if (isAdd) {
                    num += 5;
                }
                getMessages();
                Log.d(TAG, "onRefresh:chatMessageList.size()=" + chatMessageList.size());
                Log.d(TAG, "onRefresh: num=" + num);
                if (num - chatMessageList.size() > 10) {
                    isAdd = false;
                }
                swipeRefreshLayout.setRefreshing(false);
                // 定位到第一行
                recyclerView.scrollToPosition(0);
            }
        });

        // 将对于该用户的未读数设置为0
        setUnreadZero();

        // 如果为系统消息，隐藏发送框
        if (driverId.equals(MessageConstant.D_SYSTEM_ID)) {
            LinearLayout linearLayout = findViewById(R.id.send_linear);
            linearLayout.setVisibility(View.GONE);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 动态注册的广播接收器要记得取消注册
        localBroadcastManager.unregisterReceiver(chatMessageReceiver);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        if (id == R.id.back) {
            finish();
        } else if (id == R.id.send_button) {
            content = inputEditText.getText().toString();
            Log.d(TAG, "onClick: content=" + content);
            ChatMessage chatMessage = new ChatMessage();
            chatMessage.setContent(content);
            chatMessage.setMessageType(ChatMessage.FROM_SENDER);
            chatMessage.setDriverId(driverId);
            chatMessageList.add(chatMessage);
            // 刷新RecyclerView的显示
            adapter.notifyItemInserted(chatMessageList.size() - 1);
            // 定位到最后一行
            recyclerView.scrollToPosition(chatMessageList.size() - 1);
            // 清空输入框
            inputEditText.setText("");
            // 发送消息
            sendToUser();
        }
    }

    /**
     * 绑定服务
     */
    private void bindService() {
        Intent bindIntent = new Intent(this, WebSocketService.class);
        bindService(bindIntent, connection, BIND_AUTO_CREATE);
    }

    /**
     * 发送消息给对应用户
     */
    private void sendToUser() {
        DateTimeFormatter formatterForId;
        DateTimeFormatter formatterForSendTime;
        String sendTime = "2000-01-01 01:00:00";
        String timeForId = "2000-01-01 01:00:00";
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            // 根据发送时间与用户id生成消息id
            formatterForId = DateTimeFormatter.ofPattern("MMddHHmmss");
            formatterForSendTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime now = LocalDateTime.now();
            sendTime = now.format(formatterForSendTime);
            timeForId = now.format(formatterForId);
        }

        Message message = new Message();
        message.setReceiverId(driverId);
        message.setContent(content);
        message.setSenderId(userId);
        message.setSendTime(sendTime);
        message.setMessageId(userId + timeForId);

        String messageString = JSON.toJSONString(message);
        myWebSocketClient.send(messageString);
    }

    /**
     * 获得聊天记录
     */
    private void getMessages() {
        String url = MessageConstant.URL + "/messages/" + user.getUserId() + "/" + driverId + "/" + num;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    String responseData = OkHttpUtils.get(url);
                    Log.d(TAG, "run: responseData:" + responseData);
                    messages = UserUtils.parseMessageJsonWithJsonObject(responseData);
                    chatMessageList = turnMessagesToChatMessages(messages);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            recyclerView.setLayoutManager(layoutManager);
                            adapter = new ChatMessageAdapter(chatMessageList);
                            recyclerView.setAdapter(adapter);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        ThreadPoolUtil.execute(runnable);
    }

    /**
     * 从Message提取有用的信息到ChatMessage中，并反转
     *
     * @param messages List<Message>
     * @return List<ChatMessage>
     */
    private List<ChatMessage> turnMessagesToChatMessages(List<Message> messages) {
        int len = messages.size();
        List<ChatMessage> chatMessages = new ArrayList<>();
        for (Message message : messages) {
            ChatMessage chatMessage = new ChatMessage();
            // 发送者为用户
            if (message.getSenderId().equals(userId)) {
                chatMessage.setMessageType(ChatMessage.FROM_SENDER);
            }
            // 否则
            else {
                chatMessage.setMessageType(ChatMessage.FROM_RECEIVER);
            }
            chatMessage.setContent(message.getContent());
            chatMessage.setDriverId(driverId);

            chatMessages.add(0, chatMessage);
        }
        return chatMessages;
    }

    /**
     * 将未读数设置为0
     */
    private void setUnreadZero() {
        String url = MessageConstant.URL + "/updateUserUnread/" + driverId + "/" + user.getUserId() + "/0";
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    String responseData = OkHttpUtils.put(url, "");
                    Log.d(TAG, "run: responseData:" + responseData);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }
}